<?php
/*
命令模式：
　　命令模式(Command Pattern)：将一个请求封装为一个对象，从而使我们可用不同的请求对客户进行参数化；对请求排队或者记录请求日志，以及支持可撤销的操作。命令模式是一种对象行为型模式，其别名为动作(Action)模式或事务(Transaction)模式。

模式动机：
　　在软件设计中，我们经常需要向某些对象发送请求，但是并不知道请求的接收者是谁，也不知道被请求的操作是哪个，我们只需在程序运行时指定具体的请求接收者即可，此时，可以使用命令模式来进行设计，使得请求发送者与请求接收者消除彼此之间的耦合，让对象之间的调用关系更加灵活。
命令模式可以对发送者和接收者完全解耦，发送者与接收者之间没有直接引用关系，发送请求的对象只需要知道如何发送请求，而不必知道如何完成请求。这就是命令模式的模式动机。

命令模式包含如下角色：
　　Command: 抽象命令类
　　ConcreteCommand: 具体命令类
　　Invoker: 调用者
　　Receiver: 接收者
　　Client:客户类
*/

header("Content-type:text/html;Charset=utf-8");
//命令接口，定义具体命令接口要实现的执行函数
interface Command{
    function execute();
}
//具体命令角色AttackCommand,指定接受者执行攻击命令
class AttackCommand implements Command{
    private $receiver;
    function __construct(Receiver $receiver){
        $this->receiver = $receiver;
    }
    function execute(){
        $this->receiver->attackAction();
    }
}
//具体命令角色DefenseCommand,指定接受者执行防御命令
class DefenseCommand implements Command{
    private $receiver;
    function __construct(Receiver $receiver){
        $this->receiver = $receiver;
    }
    function execute(){
        $this->receiver->defenseAction();
    }
}
//接受者，执行具体命令角色的命令
class Receiver{
    private $name;
    function __construct($name){  //赵日天
        $this->name = $name;
    }
    function attackAction(){
        echo $this->name."执行了攻击命令";
    }
    function defenseAction(){
        echo $this->name."执行了防御命令";
    }
}
//请求者，请求具体命令的执行
class Invoker{
    private $concreteCommand;
    function __construct($concreteCommand){
        $this->concreteCommand = $concreteCommand;
    }
    function executeCommand(){
        $this->concreteCommand->execute();
    }
}

//客户端角色
class Client{
    function __construct(){
        $receiverZhao = new Receiver("赵日天");
        $attackCommand = new AttackCommand($receiverZhao);
        $attackInvoker = new Invoker($attackCommand);
        $attackInvoker->executeCommand();

        $receiverYe = new Receiver("叶良辰");
        $defenseCommand = new DefenseCommand($receiverYe);
        $defenseInvoker = new Invoker($defenseCommand);
        $defenseInvoker->executeCommand();
    }
}

//测试：
new Client();